package com.xykj.service.impl;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.xykj.common.entry.ChinaIndex;
import com.xykj.mapper.ChinaIndexMapper;
import com.xykj.service.FCrawlerService;
import com.xykj.web.websocket.NewsWebSocketHandler;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 中国指数爬虫类
 */

@Slf4j
@Service
public class ChinaIndexCrawlerService implements FCrawlerService {

    @Autowired
    private ChinaIndexMapper chinaIndexMapper;

    @Autowired
    private NewsWebSocketHandler webSocketHandler;

    // 使用原生Java HTTP客户端替代OkHttp
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36";

    // 目标网站URL
    private static final String TARGET_URL = "https://quote.eastmoney.com/center/qqzs.html";

    String table = "china_index";

    /**
     * 定时爬取东方财富网指数数据服务。
     * <p>
     * 实现步骤：
     * 1. 使用Jsoup定时请求东方财富网API。（ 发送HTTP请求并解析HTML（或类似结构）内容）
     * 2. 解析返回的JSONP数据，使用Gson提取指数信息。
     * 3. 批量删除旧数据并插入新数据到数据库。
     * 4. 通过WebSocket广播最新数据给前端。
     * <p>
     * 关键点：动态时间戳URL、JSONP解析、批量数据库操作、定时任务、WebSocket推送。
     */

    // 基础URL
    String apiUrl = "https://push2.eastmoney.com/api/" + "qt/clist/get?np=1&fltt=1&invt=2&cb=jQuery37" + "1018959658534922685_1747395228450&fs=i%3A1." + "000001%2Ci%3A0.399001%2Ci%3A0.399005%2Ci%3A0" + ".399006%2Ci%3A1.000300%2Ci%3A100.HSI%2Ci%3A100" + ".HSCEI%2Ci%3A124.HSCCI%2Ci%3A100.TWII%2Ci%3A10" +
            "0.N225%2Ci%3A100.KOSPI200%2Ci%3A100.KS11%2Ci%3" + "A100.STI%2Ci%3A100.SENSEX%2Ci%3A100.KLSE%2Ci%3" + "A100.SET%2Ci%3A100.PSI%2Ci%3A100.KSE100%2Ci%3A" + "100.VNINDEX%2Ci%3A100.JKSE%2Ci%3A100.CSEALL&fie" + "lds=f12%2Cf13%2Cf14%2Cf292%2Cf1%2Cf2%2Cf4%2Cf3%" + "2Cf152&fid=&pn=1&pz=100&po=1&ut=fa5fd1943c7b386" + "f172d6893dbfba10b&dect=1&wbp2u=%7C0%7C0%7C0%7Cw" + "eb&_=";

    @Override
    @Scheduled(fixedRate = 60000)
    @Transactional(rollbackFor = Exception.class)
    public boolean crawl() {
        try {
            log.info("开始爬取中国指数数据...");
            apiUrl=getFullApiUrl();
            // 发送HTTP请求时指定User-Agent（模拟浏览器，避免被反爬）
            String jsonpResponse = Jsoup.connect(apiUrl)
                    .userAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36")
                    .ignoreContentType(true)
                    .execute()
                    .body();
            // 提取JSON部分（去掉JSONP包装）
            String json = jsonpResponse.substring(
                    jsonpResponse.indexOf('(') + 1,
                    jsonpResponse.lastIndexOf(')')
            );
            // 使用Gson解析JSON
            JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
            JsonObject data = jsonObject.getAsJsonObject("data");
            List<ChinaIndex> chinaIndices = parseChinaIndices(data);
            // 保留前100条数据
            List<ChinaIndex> top100 = chinaIndices.subList(0, Math.min(100, chinaIndices.size()));
            // 保存到数据库
            if (!top100.isEmpty()) {
                updateDatabase(top100);
                log.info("成功更新 {} 条中国指数数据", top100.size());
                return true;
            } else {
                log.warn("未解析到有效的指数数据");
                return false;
            }

        } catch (IOException e) {
            log.error("获取指数数据失败: {}", e.getMessage());
            return false;
        }
    }


    private static List<ChinaIndex> parseChinaIndices(JsonObject data) {
        List<ChinaIndex> result = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        // 处理data为null的情况（根据文档报错信息补充）
        if (data == null || data.get("diff") == null) {
            log.warn("返回数据中diff字段为空");
            return result;
        }
        data.getAsJsonArray("diff").forEach(element -> {
            JsonObject item = element.getAsJsonObject();
            ChinaIndex index = new ChinaIndex();
            index.setIndexName(item.get("f14").getAsString()); // 指数名称
            // 处理f2可能为null或非数字的情况
            if (item.has("f2") && !item.get("f2").isJsonNull()) {
                index.setLatestPrice(BigDecimal.valueOf(item.get("f2").getAsLong())); // 最新价格
            } else {
                index.setLatestPrice(BigDecimal.ZERO);
                log.warn("指数{}的f2字段为空或非数字", item.get("f14").getAsString());
            }
            index.setCreatedAt(now);
            index.setUpdatedAt(now);
            result.add(index);
        });
        return result;
    }

    // 获取完整的URL，包含动态生成的时间戳
    public String getFullApiUrl() {
        long timestamp = System.currentTimeMillis();
        return (apiUrl+ timestamp);
    }

    /**
     * 更新数据库
     */
    private void updateDatabase(List<ChinaIndex> indexes) {
        if (indexes == null || indexes.isEmpty()) return;
        try {
            // 1. 获取现有记录的ID
            List<Long> existingIds = chinaIndexMapper.selectExistingIds();
            // 2. 批量删除旧数据
            if (existingIds != null && !existingIds.isEmpty()) {
                chinaIndexMapper.batchDelete(existingIds);
            }
            // 3. 批量插入新数据
            chinaIndexMapper.batchInsert(indexes);
            // 4. WebSocket通知前端
            webSocketHandler.broadcast(indexes);
        } catch (Exception e) {
            log.error("数据库更新失败", e);
        }
    }
}